package com.dongdongqiang.daogenerator;

import com.dongdongqiang.daogenerator.config.DDQDAOConfig;
import com.dongdongqiang.daogenerator.exception.DDQException;
import com.dongdongqiang.daogenerator.handler.IDeleteHandler;
import com.dongdongqiang.daogenerator.handler.IInsertHandler;
import com.dongdongqiang.daogenerator.handler.IQueryHandler;
import com.dongdongqiang.daogenerator.handler.IUpdateHandler;
import com.dongdongqiang.daogenerator.handler.impl.DeleteHandlerImpl;
import com.dongdongqiang.daogenerator.handler.impl.InsertHandlerImpl;
import com.dongdongqiang.daogenerator.handler.impl.QueryHandlerImpl;
import com.dongdongqiang.daogenerator.handler.impl.UpdateHandlerImpl;
import com.dongdongqiang.daogenerator.sqlbuilder.mysql.MysqlDeleteSQLBuilder;
import com.dongdongqiang.daogenerator.sqlbuilder.mysql.MysqlInsertSQLBuilder;
import com.dongdongqiang.daogenerator.sqlbuilder.mysql.MysqlQuerySQLBuilder;
import com.dongdongqiang.daogenerator.sqlbuilder.mysql.MysqlUpdateSQLBuilder;
import com.dongdongqiang.daogenerator.sqlbuilder.postgresql.PostgresqlDeleteSQLBuilder;
import com.dongdongqiang.daogenerator.sqlbuilder.postgresql.PostgresqlInsertSQLBuilder;
import com.dongdongqiang.daogenerator.sqlbuilder.postgresql.PostgresqlQuerySQLBuilder;
import com.dongdongqiang.daogenerator.sqlbuilder.postgresql.PostgresqlUpdateSQLBuilder;
import com.dongdongqiang.daogenerator.statement.InsertPrepareStatementSetter;
import com.dongdongqiang.daogenerator.statement.UpdatePrepareStatementSetter;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.List;

/**
 * dongdongqiang-DAO
 * Created by ZZB on 2017/9/24.
 */
public class DDQDAO implements IInsertHandler,IUpdateHandler,IDeleteHandler,IQueryHandler {
    private IInsertHandler IInsertHandler;
    private IQueryHandler IQueryHandler;
    private IUpdateHandler IUpdateHandler;
    private IDeleteHandler IDeleteHandler;
    private DataSource dataSource;

    public DDQDAO(DDQDAOConfig ddqdaoConfig){
        this.dataSource = ddqdaoConfig.getDataSource();

        if(ddqdaoConfig.getJdbcType() == null || ddqdaoConfig.getJdbcType().equals("")
                || ddqdaoConfig.getJdbcType().toUpperCase().equals("MYSQL")){
            IInsertHandler = new InsertHandlerImpl(new MysqlInsertSQLBuilder(),new InsertPrepareStatementSetter());
            IQueryHandler = new QueryHandlerImpl(new MysqlQuerySQLBuilder());
            IUpdateHandler = new UpdateHandlerImpl(new MysqlUpdateSQLBuilder(),new UpdatePrepareStatementSetter());
            IDeleteHandler = new DeleteHandlerImpl(new MysqlDeleteSQLBuilder());

        } else if(ddqdaoConfig.getJdbcType().toUpperCase().equals("POSTGRESQL")){
            IInsertHandler = new InsertHandlerImpl(new PostgresqlInsertSQLBuilder(),new InsertPrepareStatementSetter());
            IQueryHandler = new QueryHandlerImpl(new PostgresqlQuerySQLBuilder());
            IUpdateHandler = new UpdateHandlerImpl(new PostgresqlUpdateSQLBuilder(),new UpdatePrepareStatementSetter());
            IDeleteHandler = new DeleteHandlerImpl(new PostgresqlDeleteSQLBuilder());
        }
    }

    @Override
    public int update(Object o,Connection conn) throws DDQException {
        return IUpdateHandler.update(o,conn);
    }

    @Override
    public int[] updateList(List<?> objects, Connection connection) throws DDQException {
        return IUpdateHandler.updateList(objects, connection);
    }

    @Override
    public int updateField(Object pk, Class<?> tClass, String updateField, Object value, Connection connection) throws DDQException {
        return IUpdateHandler.updateField(pk, tClass, updateField, value, connection);
    }

    @Override
    public int updateListField(List<?> pk, Class<?> tClass, String updateField, Object value, Connection connection) throws DDQException {
        return IUpdateHandler.updateListField(pk, tClass, updateField, value, connection);
    }

    @Override
    public int insert(Object o, Connection connection) throws DDQException {
        return IInsertHandler.insert(o, connection);
    }

    @Override
    public int[] insertList(List<?> objects, Connection connection) throws DDQException {
        return IInsertHandler.insertList(objects, connection);
    }

    @Override
    public <T> int deleteByPk(Object pk, Class<T> tClass, Connection connection) throws DDQException {
        return IDeleteHandler.deleteByPk(pk, tClass, connection);
    }

    @Override
    public <T> int[] deleteInPk(List<Object> pk, Class<T> tClass, Connection connection) throws DDQException {
        return IDeleteHandler.deleteInPk(pk, tClass, connection);
    }

    @Override
    public int delete(Object o, Connection connection) throws DDQException {
        return IDeleteHandler.delete(o,connection);
    }

    @Override
    public <T> T getBy(Object pk, Class<T> tClass, Connection connection) {
        return IQueryHandler.getBy(pk, tClass, connection);
    }

    @Override
    public <T> T findBy(String c, Object o, Class<T> tClass, Connection connection) {
        return IQueryHandler.findBy(c, o, tClass, connection);
    }

    @Override
    public <T> List<T> queryBy(String c, Object o, Class<T> tClass, Connection connection) {
        return IQueryHandler.queryBy(c, o, tClass, connection);
    }

    @Override
    public <T> long countBy(String c, Object o, Class<T> tClass, Connection connection) {
        return IQueryHandler.countBy(c, o, tClass, connection);
    }

    @Override
    public <T> List<T> query(String sql, Class<T> tClass, Connection connection) {
        return IQueryHandler.query(sql, tClass, connection);
    }

    @Override
    public <T> List<T> query(String sql, Class<T> tClass, Object[] objects, Connection connection) {
        return IQueryHandler.query(sql, tClass, objects, connection);
    }

    @Override
    public long queryCount(String sql, Connection connection) {
        return IQueryHandler.queryCount(sql, connection);
    }

    @Override
    public long queryCount(String sql, Object[] objects, Connection connection) {
        return IQueryHandler.queryCount(sql, objects, connection);
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public DataSource getDataSource() {
        return dataSource;
    }
}
